/*
 * AlarmManager.c
 *
 *  Created on: Mar 5, 2012
 *      Author: mikaelgra
 */

#include "AlarmManager.h"
#include "Alarm.h"
#include "ArrayList.h"
#include "gpio/System.h"
#include "gpio/Define.h"

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>


/**
 * ArrayList of all alarms associated with the AlarmManager
 */
struct stArrayList_t *Alarms = NULL;

/**
 * Initializes the AlarmManager. This must be called
 * before any other methods.
 */
void AlarmManager_Initialize(void)
{
	Alarms = ArrayList_New(ArrayList_AddressComparison);
}

/**
 * Finalizes the AlarmManager. This must be the last
 * method called on the AlarmManager.
 */
void AlarmManager_Finalize(void)
{
	// make sure to reset all used GPIO pins, empty array list and finalize alarms
	while(!ArrayList_IsEmpty(Alarms))
	{
		struct stAlarm_t* alarm = ArrayList_Get(Alarms, 0);
		AlarmManager_RemoveAlarm(alarm);
		Alarm_Finalize(alarm);
	}

	// lastly, free ArrayList
	ArrayList_Finalize(Alarms);
}

/**
 * Adds an Alarm to the AlarmManager.
 *
 * @param alarm
 * 		This is the Alarm to be added
 */
void AlarmManager_AddAlarm(struct stAlarm_t* alarm)
{
	ArrayList_Add(Alarms, alarm);
	// defPinLow does not do anything for input, it is just a dummy
	System_CreateGpioPin(alarm->gpioInputPin, defPinInput, defPinLow);
	System_CreateGpioPin(alarm->gpioOutputPin, defPinOutput, defPinLow);
}

/**
 * Removes an Alarm from the AlarmManager.
 *
 * @param alarm
 * 		This is the Alarm to be removed
 */
void AlarmManager_RemoveAlarm(struct stAlarm_t* alarm)
{
	ArrayList_Remove(Alarms, alarm);
	System_RemoveGpioPin(alarm->gpioInputPin);
	System_RemoveGpioPin(alarm->gpioOutputPin);
}

/**
 * Gets the number of alarms associated with the
 * AlarmManager
 *
 * @return
 * 		The number of alarms
 */
int AlarmManager_GetAlarmCount()
{
	return ArrayList_GetSize(Alarms);
}

/**
 * Gets the Alarm at the specified index.
 *
 * @param index
 * 		Is the index of the alarm to be retrieved
 *
 * @return
 * 		Is the alarm at the index to be retrieved
 */
struct stAlarm_t* AlarmManager_GetAlarmAt(int index)
{
	return (struct stAlarm_t*)ArrayList_Get(Alarms, index);
}


struct stAlarm_t* AlarmManager_CheckAlarms()
{
	int index;
	for(index = 0; index < ArrayList_GetSize(Alarms); index++)
	{
		struct stAlarm_t* alarm = ArrayList_Get(Alarms, index);
		int value = System_ReadValue(alarm->gpioInputPin);
#ifdef DEBUG
		printf("%d -> %d\n", alarm->gpioInputPin, value);
#endif
		if(alarm->enAlarmState == eEnabled && value == alarm->triggerValue)
		{
			return alarm;
		}
	}
	return NULL;
}

